/*************************************************************
 * 
 * CopyRight(c)2007, http://www.moorwind.com/
 * email:ezhung@gmail.com
 * for free, but a email permission would be nice
 * 
 ************************************************************/
package kono.utils
{
	public class D3Array
	{
		private var _width:uint;
		private var _height:uint;
		private var _depth:uint;
		
		private var _array:Array;
		
		//@param width:三维数组宽度，the colum of the 3D array
		//@param height:三维数组长度，the row of the 3D array
		//@param depth:三维数组长度，the depth of the 3D array
		public function D3Array(width:uint = 1, height:uint = 1, depth:uint = 1)
		{
			_array = new Array((_width = width) * (_height = height) * (_depth = depth));
		}
		
		//取得数组大小， get the total number of the 3D array's cell
		public function get size():uint
		{
			return _width * _height * _depth;
		}
		
		public function get width():uint
		{
			return _width;
		}
		
		public function get height():uint
		{
			return _height;
		}
		
		public function get depth():uint
		{
			return _depth;
		}
		
		//返回指定坐标（x,y,z）位置的数据，read the value at the given point (x,y,z)
		public function getItem(x:uint, y:uint, z:uint):*
		{
			return _array[uint(z * _width * _height + y * _width + x)];
		}
		
		//设定指定位置（x,y,z）的数值. set the value at the given point (x,y,z)
		public function addItem(x:uint, y:uint, z:uint, data:*):void
		{
			_array[uint(z * _width * _height + y * _width + x)] = data;
		}
		
		//填充数据， fill each of the 3D array's cell with the given data
		public function fill(data:*):void
		{
			var s:uint = _width * _height * _depth;
			for(var i:uint = 0; i < s; i++)
			{
				_array[i] = data;
			}
		}
		
		//重设数组大小，resize the 3D array to match the given width and height 
		public function resize(width:uint, height:uint, depth:uint):void
		{
			var temp:Array = _array.concat();	
			_array = new Array(width * height * depth);
			
			var min_width:uint = width < _width ? width : _width;
			var min_height:uint = height < _height ? height : _height;
			var min_depth:uint = depth < _depth ? depth : _depth;
			
			var i:uint, j:uint, k:uint;
			for(i = 0; i < min_width; i++)
			{
				for(j=0; j< min_height; j++)
				{
					for(k = 0; j < min_depth; k++)
					{
						_array[uint(k * width * height + j * width + i)] = temp [uint(k * _width * _height + j * _width + i)];
					}
				} 
			}
			_width = width;
			_height = height;
			_depth = depth;
		}
						
		//判断数组是否包含某个数据， chack if the 3D array contains the given data
		public function contains(data:*):Boolean
		{
			var s:uint = _width * _height * _depth;
			for(var i:uint; i < s; i++)
			{
				if(_array[i] == data)
				{
					return true;
				}
			}
			return false;
		}
		
		//返回一维数组, convert the 3D array to a linear array
		public function toArray():Array
		{
			return _array;
		}
		
		//返回2维数组信息， print the information of the 3D array
		public function toString():String
		{
			return ("[3-Dimensional Array, width=" + _width + " height=" + _height + "depth=" + _depth + " size=" + _width*_height*_depth +"]");
		}
	}
}